﻿using System;
using System.Collections;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace SanguoXCiv.Logic
{
    class groundBlock
    {
        public string type;
        public int x;
        public int y;
        public int size;

        public groundBlock(int x = 0, int y = 0, string type = @"block_plain")
        {
            this.x = x;
            this.y = y;
            this.type = type;
            this.size = 64;
        }

        public Vector2 GetPos()
        {
            Vector2 pos = new Vector2(this.x * this.size, this.y * this.size);
            return pos;
        }
    }

    class Battlefield
    {
        public int width;
        public int height;

        public ArrayList blockList;

        public Battlefield(int width, int height)
        {
            this.width = width;
            this.height = height;
            this.blockList = new ArrayList();
            for(int i = 0; i < width; i++)
                for (int j = 0; j < height; j++)
                {
                    groundBlock newBlock = new groundBlock(i, j);
                    this.blockList.Add(newBlock);
                }
        }

        public groundBlock GetBlock(int x, int y)
        {
            groundBlock nullBlock = new groundBlock();
            foreach (groundBlock selBlock in this.blockList)
            {
                if (selBlock.x == x && selBlock.y == y)
                    return selBlock;
                else continue;
            }

            return nullBlock;
        }
    }

    class Unit
    {
        public string type;
        public float x;
        public float y;
        public int team;

        public int health;
        public int attackPower;
        public float attackFreq;
        public float attackStun;
        public int attackRange;
        public float movingSpeed;

        public Queue path;
        public Unit attackTarget;

        public int isSelected;

        public Unit(float x = 0, float y = 0, string type = @"null", int team = 0)
        {
            this.type = type;
            this.x = x;
            this.y = y;
            this.team = team;
            this.path = new Queue();
            this.isSelected = 0;
            this.attackStun = 100;
            this.attackTarget = null;

            if (this.type == @"infantry")
            {
                this.health = 200;
                this.attackPower = 5;
                this.attackFreq = 2f;
                this.attackRange = 1;
                this.movingSpeed = 1.0f;
            }
            else if (this.type == @"archer")
            {
                this.health = 150;
                this.attackPower = 20;
                this.attackFreq = 2f;
                this.attackRange = 2;
                this.movingSpeed = 1.0f;
            }
            else
            {
                this.health = 200;
                this.attackPower = 5;
                this.attackFreq = 2f;
                this.attackRange = 1;
                this.movingSpeed = 1.0f;
            }
        }

        public bool isMouseOver(float mouseX, float mouseY)
        {
            if (this.x < mouseX && this.x + 64 > mouseX && this.y < mouseY && this.y + 64 > mouseY)
                return true;
            else return false;
        }

        public Vector2 GetPos()
        {
            Vector2 curPos = new Vector2(this.x, this.y);
            return curPos;
        }

        public void Move()
        {
            if (this.path.Count > 0)
            {
                groundBlock destination = new groundBlock();
                destination = this.path.Peek() as groundBlock;
                Vector2 distance = new Vector2(destination.x * destination.size - this.x, destination.y * destination.size - this.y);
                if (distance.Length() < 0.1f)
                {
                    this.path.Dequeue();
                    if (this.path.Count > 0)
                        destination = this.path.Peek() as groundBlock;
                    else
                        return; // Already on the final destination, stops moving
                }
                if (destination.x * destination.size > this.x)
                {
                    this.x += this.movingSpeed;
                }
                else if (destination.x * destination.size < this.x)
                {
                    this.x -= this.movingSpeed;
                }
                else if (destination.y * destination.size > this.y)
                {
                    this.y += this.movingSpeed;
                }
                else if (destination.y * destination.size < this.y)
                {
                    this.y -= this.movingSpeed;
                }
            }
            else
                return;
        }

        public void SetAttackTarget(Unit enemy)
        {
            this.attackTarget = enemy;
        }

        public void RemoveAttackTarget()
        {
            this.attackTarget = null;
        }

        public void Attack()
        {
            if (this.attackTarget != null) // If target exsits
            {
                // If target within range
                if ((Math.Abs(this.x - this.attackTarget.x) <= this.attackRange * 64 && this.y == this.attackTarget.y) ||
                    (Math.Abs(this.y - this.attackTarget.y) <= this.attackRange * 64 && this.x == this.attackTarget.x))
                {
                    this.path.Clear();
                    if (this.attackStun > 0) // Attack interval
                    {
                        this.attackStun -= this.attackFreq;
                    }
                    else // Perform attack
                    {
                        this.attackStun = 100;
                        this.attackTarget.health -= this.attackPower;
                    }
                }
            }
        }

    }
}